import axios from 'axios'
import router from '@/router/index'
import HttpCode from '@/utils/const/http'
import {prefix} from "@/const.config.js";
import Vue from 'vue'
import {notification} from 'ant-design-vue'

const $axios = axios.create({timeout: 1000 * 12, baseURL: prefix});
let whiteList = ['/rest/ignore', '/mbap-auth/oauth/token', '/mbap-pp/rest/system/common/csrf', '/mbap-pp/rest/system/common/createValidCode', '/mbap-auth/oauth/getKeystr'] // 请求白名单 无需携带token
export const setIgnoreList = (ignoreList) => {
    whiteList.push(...ignoreList)
}
$axios.interceptors.request.use(
    function (config) {
        // let whiteList = ['upload/', 'getUploadUrl', '/auth/oauth/token', '/system/token'] // 请求白名单 无需携带token
        let flag = true; // 判断是否需要携带token
        // 白名单不需要携带token
        for (let index = 0; index < whiteList.length; index++) {
            const reg = new RegExp('^' + whiteList[index])
            if (reg.test(config.url)) {
                flag = false;
                break
            }
        }
        if (!flag) {
            return config
        }
        const token = Vue.ls.get("token")
        /**
         * 判断是否有token
         * 是：携带token
         * 否：进入登录页
         */
        if (token) {
            /**
             * 设置用户认证token
             */
            config.headers['Authorization'] = `Bearer ${token.access_token}`
        }
        //在发送请求之前做某事
        return config;
    },
    function (error) {
        //请求错误时做些事
        return Promise.reject(error);
    });

//添加响应拦截器
$axios.interceptors.response.use(
    async function (response) {
        let data;
        /**
         * 判断数据类型是否是文件类型
         */
        if (['arraybuffer', 'blob'].indexOf(response.request.responseType) === -1) {
            // IE9时response.data是undefined，因此需要使用response.request.responseText(Stringify后的字符串)
            if (response.data) {
                data = JSON.parse(response.request.responseText)
            } else {
                data = response.data
            }
        }
        /**
         * 图片类型的数据处理
         */
        if (response.request.responseType.toUpperCase() === 'arraybuffer'.toUpperCase()) {
            return response
        }
        /**
         * 统一处理文件信息
         */
        if (response.request.responseType.toUpperCase() === 'blob'.toUpperCase()) {
            const filename = response.headers["content-disposition"];
            const blob = new Blob([response.data]);
            var downloadElement = document.createElement("a");
            var href = window.URL.createObjectURL(blob);
            downloadElement.href = href;
            if (filename) {
                downloadElement.download = decodeURI(filename.split("filename=")[1]);
            } else {
                console.error('请求文件错误')
                return response.data
            }
            document.body.appendChild(downloadElement);
            downloadElement.click();
            document.body.removeChild(downloadElement);
            window.URL.revokeObjectURL(href);
            return response.data
        }
        if (response.data.code === 501 || response.data.code === 401) {
            router.push({
                path: '/login'
            })
        }

        // IE9时response.data是undefined，因此需要使用response.request.responseText(Stringify后的字符串)
        if (response.data) {
            data = JSON.parse(response.request.responseText)
        } else {
            data = response.data
        }
        // 判断返回的状态
        switch (data.code) {
            case HttpCode.SUCCESS:
                return data;
            case HttpCode.FAIL:
                notification.error({message: "服务器繁忙、请稍后再试!"});
                break;
            case HttpCode.SERVER_ERROR:
                notification.error({message: "执行异常"});
                break;
            case HttpCode.PEFRESHTOKEN_OVERTIME:
                notification.warning({message: "认证过期"});
                router.push({
                    path: '/login'
                })
                return
            case HttpCode.TOKEN_INVALID:
            case HttpCode.SIGN_INVALID:
                notification.warning({message: "认证无效"});
                router.push({
                    path: '/login'
                })
                return
            case HttpCode.AUTO_EXCEPTION:
                notification.error({message: "身份验证异常"});
                return
            case HttpCode.TOKEN_OVERTIME:
                // await resResetToken();
                return;
            case HttpCode.EXISTENCE_EXCEPTION:
                notification.error({message: "数据不存在"});
                break;
            case HttpCode.PARAM_ERROR:
                notification.error({message: "不合法参数"});
                return;
            case HttpCode.ACCESS_DEINE:
                notification.error({message: "权限不足"});
                break;
            case HttpCode.FORCED_OUT:
                notification.error({message: "强制退出"});
                break;
            default:
                notification.error({message: data.message});
                break
        }
        return Promise.reject('error');
    },
    async err => {
        console.log(err)
        let response = err.response;
        if (response.status === 500) {
            notification.error({message: '服务器错误，请稍后再试！'});
            return
        }
        /**
         * 判断请求状态是否是401
         */
        if (response.status === 401) {
            // await resResetToken()
        }
        if (response.status === 404) {
            notification.error({message: "请求失败"});
        }
    });

/**
 * 发送get 请求函数
 * @param url 请求地址
 * @param params 请求参数
 * @param headers 请求头信息
 * @returns {*}
 */
export const getAction = (url, params, headers = {}) => {

    return $axios.request({
        url,
        method: "get",
        params,
        headers
    })
}

/**
 * 发送post 请求的函数
 * @param url 请求地址
 * @param data 请求数据
 * @param params 请求参数
 * @param headers 请求头信息
 * @returns {*}
 */
export const postAction = (url, data, params, headers = {}) => {
    return $axios.request({
        url,
        method: "post",
        params,
        data,
        headers
    })
}
/**
 * 发送del 请求函数
 * @param url 请求地址
 * @param params 请求参数
 * @param headers 请求头信息
 * @returns {*}
 */
export const delAction = (url, params,data, headers = {}) => {

    return $axios.request({
        url,
        method: "delete",
        params,
        data,
        headers
    })
}

/**
 * 发送PUT 请求的函数
 * @param url 请求地址
 * @param data 请求数据
 * @param params 请求参数
 * @param headers 请求头信息
 * @returns {*}
 */
export const putAction = (url, data, params, headers = {}) => {
    return $axios.request({
        url,
        method: "put",
        data,
        params,
        headers
    })
}

/**
 * （二进制文件流）请求函数
 * @param option 配置信息
 * @returns {*}
 */
export const blobAction = (option) => {
    return $axios.request({...option, responseType: "blob"})
}
/**
 * 图片的请求函数
 * @param option 配置信息
 * @returns {*}
 */
export const imageAction = (option) => {
    return $axios.request({...option, responseType: "arraybuffer"})
}
/**
 * 发送任意请求
 * @param option 请求的参数
 * @returns {Promise<string>|*}
 */
const httpAction = (option) => {
    if (option.method.toUpperCase() === 'GET') {
        return getAction(option.url, option.params, option.headers)
    } else if (option.method.toUpperCase() === 'POST') {
        return postAction(option.url, option.data, option.params, option.headers)
    } else if (option.method.toUpperCase() === 'DELETE') {
        return delAction(option.url, option.data, option.params, option.headers)
    } else if (option.method.toUpperCase() === 'PUT') {
        return putAction(option.url, option.data, option.params, option.headers)
    } else {
        return Promise.resolve("ok")
    }
}
export default httpAction